package com.whfc.fmam.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.DelFlag;
import com.whfc.common.enums.EnableState;
import com.whfc.common.exception.BizException;
import com.whfc.common.generator.KeyGeneratorUtil;
import com.whfc.common.result.ListData;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.PageUtil;
import com.whfc.common.util.PinyinUtil;
import com.whfc.fmam.dao.FmamMatMapper;
import com.whfc.fmam.dao.FmamMatTypeMapper;
import com.whfc.fmam.dao.FmamMatUnitMapper;
import com.whfc.fmam.dao.FmamUnitMapper;
import com.whfc.fmam.entity.bo.FmamMat;
import com.whfc.fmam.entity.bo.FmamMatType;
import com.whfc.fmam.entity.bo.FmamUnit;
import com.whfc.fmam.entity.dto.*;
import com.whfc.fmam.entity.qo.*;
import com.whfc.fmam.map.MatMap;
import com.whfc.fmam.map.MatTypeMap;
import com.whfc.fmam.redis.FmamMatTypeRedisDao;
import com.whfc.fmam.service.FmamMatService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author sun_guodong
 * @description 材料服务
 * @date 2019-11-19
 */
@DubboService(interfaceClass = FmamMatService.class, version = "1.0.0")
public class FmamMatServiceImpl implements FmamMatService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FmamMatTypeMapper fmamMatTypeMapper;

    @Autowired
    private FmamMatMapper fmamMatMapper;

    @Autowired
    private FmamUnitMapper fmamUnitMapper;

    @Autowired
    private FmamMatUnitMapper fmamMatUnitMapper;


    @Autowired
    private MatTypeMap matTypeMap;

    @Autowired
    private MatMap matMap;

    @Autowired
    private FmamMatTypeRedisDao fmamMatTypeRedisDao;


    @Override
    public List<FmamMatTypeDTO> getMatTypeListByDeptId(Integer deptId, String keyword) throws BizException {
        logger.info("根据组织机构获取所有的材料类别服务，deptId:{},keyword:{}", deptId, keyword);
        List<FmamMatTypeDTO> list = fmamMatTypeMapper.selectMatTypeList(deptId, keyword);
        return list;
    }

    @Override
    public void matTypeAdd(MatTypeAddQO request) throws BizException {
        logger.info("新增材料类别服务，MatTypeAddQO:{}", request.toString());
        String fullCode = request.getFullCode();
        Integer deptId = request.getDeptId();
        FmamMatType fmamMatType = fmamMatTypeMapper.selectByFullCodeAndDeptId(fullCode, deptId);
        if (fmamMatType != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该编码已存在");
        }

        Long pid = request.getPid();
        FmamMatType matType = matTypeMap.to(request);
        matType.setPid(pid == null ? 0 : pid);
        matType.setId(KeyGeneratorUtil.genLongId());
        matType.setMinusDiff(getNegative(request.getMinusDiff()));
        fmamMatTypeMapper.insertSelective(matType);
        //保存材料类型至缓存
        fmamMatTypeRedisDao.put(request.getDeptId(), matType.getId(), matType);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, BizException.class}, transactionManager = "fmamTransactionManager")
    public void matTypeEdit(MatTypeEditQO request) throws BizException {
        logger.info("编辑材料类别服务，MatTypeEditQO:{}", request.toString());
        Long id = request.getId();
        String fullCode = request.getFullCode();
        Integer deptId = request.getDeptId();
        Integer changeFlag = request.getChangeFlag();
        Integer diffType = request.getDiffType();
        Double plusDiff = request.getPlusDiff();
        Double minusDiff = getNegative(request.getMinusDiff());


        FmamMatType fmamMatType = fmamMatTypeMapper.selectByFullCodeAndDeptId(fullCode, deptId);
        if (fmamMatType != null && !fmamMatType.getId().equals(request.getId())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该编码已存在");
        }

        // 判断该材料类别下有没有材料
        List<FmamMatDTO> fmamMatDTOS = fmamMatMapper.selectByMatTypeId(id, null);
        if (fmamMatDTOS.size() > 0 && (fmamMatType == null || !fmamMatType.getFullCode().equals(request.getFullCode()))) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该材料类别下有材料,不能编辑该材料类别编码");
        }

        //更新材料类别
        FmamMatType matType = matTypeMap.to(request);
        matType.setUpdateTime(new Date());
        matType.setMinusDiff(minusDiff);
        fmamMatTypeMapper.updateByPrimaryKeySelective(matType);
        //保存材料类型至缓存
        fmamMatTypeRedisDao.put(request.getDeptId(), matType.getId(), matType);
        //更新材料类别子节点和子材料的偏差值
        if (changeFlag == 1) {
            List<Long> ids = getDescendantMatTypeIdList(id);
            //修改材料类别偏差
            fmamMatTypeMapper.updateDiffByPid(ids, diffType, plusDiff, minusDiff);
            //修改材料的偏差
            fmamMatMapper.updateDiffByMatTypeId(request.getDeptId(), ids, diffType, plusDiff, minusDiff);
        }


    }

    @Override
    public void matTypeDel(Long id) throws BizException {
        logger.info("删除材料类别服务，id:{}", id);
        FmamMatType fmamMatType = fmamMatTypeMapper.selectByPrimaryKey(id);
        if (fmamMatType == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该材料类型不存在。");
        }
        List<FmamMatType> list = fmamMatTypeMapper.selectByPid(id);
        if (list.size() > 0) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该材料类别下还有子节点，不能删除。");
        }
        fmamMatTypeMapper.deleteLogicById(id);
        //清除缓存中的材料类型
        fmamMatTypeRedisDao.del(fmamMatType.getDeptId(), id);
    }


    @Override
    public PageData<FmamMatDTO> matList(Long matTypeId, Integer pageNum, Integer pageSize, String keyword) throws BizException {
        logger.info("材料列表服务，matTypeId:{},pageNum:{},pageSize:{},keyword:{}", matTypeId, pageNum, pageSize, keyword);
        PageHelper.startPage(pageNum, pageSize);
        List<FmamMatDTO> list = fmamMatMapper.selectByMatTypeId(matTypeId, keyword);
        PageHelper.clearPage();

        for (FmamMatDTO fmamMatDTO : list) {
            Long matId = fmamMatDTO.getId();
            List<FmamMatUnitDTO> fmamMatUnitDTOS = fmamMatUnitMapper.selectUnitList(matId);
            fmamMatDTO.setUnitList(fmamMatUnitDTOS);
        }

        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public ListData<FmamMatDTO> matList(Integer deptId, Long matTypeId) {
        logger.info("获取所有材料列表服务，deptId:{},matTypeId:{}", deptId, matTypeId);
        List<FmamMatDTO> list = null;
        if (matTypeId != null) {
            list = fmamMatMapper.selectByMatTypeId(matTypeId, null);
        } else {
            list = fmamMatMapper.selectByDeptId(deptId, null);
        }

        ListData<FmamMatDTO> listData = new ListData<>(list);
        return listData;
    }

    @Override
    public PageData<FmamMatDTO> matList(Integer deptId, Integer pageNum, Integer pageSize, String keyword) throws BizException {
        logger.info("材料列表服务，deptId:{},pageNum:{},pageSize:{},keyword:{}", deptId, pageNum, pageSize, keyword);

        PageHelper.startPage(pageNum, pageSize);
        List<FmamMatDTO> list = fmamMatMapper.selectByDeptId(deptId, keyword);
        PageHelper.clearPage();

        for (FmamMatDTO fmamMatDTO : list) {
            Long matId = fmamMatDTO.getId();
            List<FmamMatUnitDTO> fmamMatUnitDTOS = fmamMatUnitMapper.selectUnitList(matId);
            fmamMatDTO.setUnitList(fmamMatUnitDTOS);
            //设置英文首字母
            if (!StringUtils.isEmpty(fmamMatDTO.getEname())) {
                fmamMatDTO.setEname(fmamMatDTO.getEname().substring(0, 1));
            }
        }
        return PageUtil.pageData(PageInfo.of(list));
    }


    @Override
    @Transactional(rollbackFor = {Exception.class, BizException.class}, transactionManager = "fmamTransactionManager")
    public void matAdd(MatAddQO request) throws BizException {
        logger.info("新增材料服务，MatAddQO:{}", request.toString());
        String fullCode = request.getFullCode();
        Integer deptId = request.getDeptId();
        FmamMat fmamMat = fmamMatMapper.selectByFullCodeAndDeptId(fullCode, deptId);
        if (fmamMat != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "编码已存在");
        }

        FmamMat record = matMap.to(request);
        record.setId(KeyGeneratorUtil.genLongId());
        record.setMinusDiff(getNegative(request.getMinusDiff()));
        record.setEname(PinyinUtil.toPinyinAbridge(request.getName()));
        fmamMatMapper.insertSelective(record);

        //插入材料单位
        Long matId = record.getId();
        List<FmamMatUnitDTO> unitList = request.getUnitList();
        if (unitList != null && !unitList.isEmpty()) {
            for (FmamMatUnitDTO fmamMatUnitDTO : unitList) {
                fmamMatUnitDTO.setMatId(matId);
                fmamMatUnitDTO.setId(KeyGeneratorUtil.genLongId());
                fmamMatUnitDTO.setDeptId(deptId);
            }
            fmamMatUnitMapper.batchInsert(unitList);
        }

    }

    @Override
    @Transactional(rollbackFor = {Exception.class, BizException.class}, transactionManager = "fmamTransactionManager")
    public void matEdit(MatEditQO request) throws BizException {
        logger.info("编辑材料服务，MatEditQO：{}", request.toString());
        String fullCode = request.getFullCode();
        Long matId = request.getId();
        Integer deptId = request.getDeptId();

        FmamMat fmamMat1 = fmamMatMapper.selectByFullCodeAndDeptId(fullCode, deptId);
        if (fmamMat1 != null && !fmamMat1.getId().equals(matId)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该编码已存在");
        }
        FmamMat fmamMat = matMap.to(request);
        fmamMat.setUpdateTime(new Date());
        fmamMat.setMinusDiff(getNegative(request.getMinusDiff()));
        fmamMat.setEname(PinyinUtil.toPinyinAbridge(request.getName()));
        fmamMatMapper.updateByPrimaryKeySelective(fmamMat);

        fmamMatUnitMapper.deleteLogicByMatId(matId);
        List<FmamMatUnitDTO> unitList = request.getUnitList();
        if (unitList != null && !unitList.isEmpty()) {
            for (FmamMatUnitDTO fmamMatUnitDTO : unitList) {
                fmamMatUnitDTO.setId(KeyGeneratorUtil.genLongId());
                fmamMatUnitDTO.setDeptId(deptId);
                fmamMatUnitDTO.setMatId(matId);
            }
            fmamMatUnitMapper.batchInsert(unitList);
        }

    }


    @Override
    public void matDel(Long id) throws BizException {
        logger.info("删除材料服务，id:{}", id);
        fmamMatMapper.deleteLogicById(id);
    }


    @Override
    public FmamMatImportResultDTO addExcelMat(Integer deptId, Collection<MatImportQO> matImportQOs, List<Map<Integer, Integer>> list) throws BizException {

        //一、添加物资类型数据
        //获取数据库中物资类型数据
        List<FmamMatType> fmamMatTypeDataList = fmamMatTypeMapper.selectSyncMatTypeList(deptId, null);//获取数据库中物资类型数据
        List<MatImportQO> matTypeSuccessList = new ArrayList<>();
        //过滤不正确的数据
        for (MatImportQO matImportQO : matImportQOs) {
            String fullCode = matImportQO.getFullCode();
            //1、过滤出非物资类型数据
            if (!StringUtils.isEmpty(fullCode) && fullCode.length() == (list.get(list.size() - 1).get(list.size())))
                continue;

            //2、验证物资类型数据是否正确
            String name = matImportQO.getName();
            //验证2.1、编码和名称都不能为null
            if (StringUtils.isEmpty(fullCode) || StringUtils.isEmpty(name)) continue;

            //验证2.2、编码不能和数据库中存在的类型数据重复
            boolean dataRepeat = false;
            if (fmamMatTypeDataList != null && fmamMatTypeDataList.size() > 0) {
                for (FmamMatType matType : fmamMatTypeDataList) {
                    if (matType.getFullCode().equals(fullCode)) {
                        dataRepeat = true;
                    }
                }
            }
            if (dataRepeat) continue;

            //验证2.3、编码不能和已通过验证，待准备添加的类型数据重复
            boolean importRepeat = false;
            if (matTypeSuccessList != null && matTypeSuccessList.size() > 0) {
                for (MatImportQO matType : matTypeSuccessList) {
                    if (matType.getFullCode().equals(fullCode)) importRepeat = true;
                }
            }
            if (importRepeat) continue;
            //通过过滤及验证的物资类型数据，添加到类型数据待添加列表
            matTypeSuccessList.add(matImportQO);
        }

        //把通过验证的物资类型数据，逐条添加至数据库
        if (matTypeSuccessList != null && matTypeSuccessList.size() > 0) {
            for (MatImportQO matImportQO : matTypeSuccessList) {
                //判断目录级别
                String fullCode = matImportQO.getFullCode();
                //遍历目录长度集合，判断目录级别
                for (int i = 0; i < list.size() - 1; i++) {
                    if (fullCode.length() == list.get(i).get(i + 1)) {
                        //查询父ID为0L，目录级别为1的一级目录的长度
                        Integer level = i + 1; //目录级别
                        if (level == 1) {
                            FmamMatType matType = new FmamMatType();
                            matType.setId(KeyGeneratorUtil.genLongId());
                            matType.setLevel(1);
                            matType.setPid(0L);
                            matType.setFullCode(fullCode);
                            matType.setName(matImportQO.getName());
                            matType.setDeptId(deptId);
                            matType.setDelFlag(DelFlag.UNDELETE.getValue());
                            Date date = new Date();
                            matType.setCreateTime(date);
                            matType.setUpdateTime(date);
                            fmamMatTypeMapper.insertSelective(matType);
                        } else {
                            String parentCode = fullCode.substring(0, list.get(i - 1).get(i));
                            //查询数据库中父级目录,并插入
                            FmamMatType parentMatType = fmamMatTypeMapper.selectByFullCodeAndDeptId(parentCode, deptId);
                            if (parentMatType != null && (parentMatType.getLevel() == level - 1)) {
                                FmamMatType matType = new FmamMatType();
                                matType.setId(KeyGeneratorUtil.genLongId());
                                matType.setLevel(level);
                                matType.setPid(parentMatType.getId());
                                matType.setFullCode(fullCode);
                                matType.setName(matImportQO.getName());
                                matType.setDeptId(deptId);
                                matType.setDelFlag(DelFlag.UNDELETE.getValue());
                                Date date = new Date();
                                matType.setCreateTime(date);
                                matType.setUpdateTime(date);
                                fmamMatTypeMapper.insertSelective(matType);
                            }
                        }
                    }
                }
            }
        } //添加物资类型数据完成


        //二、添加物资数据
        //获取全表物资数据
        List<FmamMat> fmamMatDataList = fmamMatMapper.selectSyncMatList(deptId, null);
        //获取全表物资类型数据
        List<FmamMatType> fmamMatTypeList = fmamMatTypeMapper.selectSyncMatTypeList(deptId, null);
        //获取全表物资材料计量单位数据
        List<FmamUnit> fmamUnitList = fmamUnitMapper.selectAllUnitDTOList();
        Integer failNumber = 0;

        List<FmamMatImportDTO> resultList = new ArrayList<>(); //批量导入结果：导入成功+导入失败 数据汇总
        List<FmamMat> matSuccessList = new ArrayList<>(); //最终批量导入数据
        for (MatImportQO matImportQO : matImportQOs) {
            String fullCode = matImportQO.getFullCode();
            //过滤出材料类型数据
            if (!StringUtils.isEmpty(fullCode) && fullCode.length() != (list.get(list.size() - 1).get(list.size()))) {
                //添加被过滤出的材料类型数据到导出结果列表（非材料数据）
                FmamMatImportDTO matTypeDTO = new FmamMatImportDTO();
                matTypeDTO.setFullCode(matImportQO.getFullCode());
                matTypeDTO.setName(matImportQO.getName());
                resultList.add(matTypeDTO);
                continue;
            }

            //校验规则1：验证表中数据的编码或者材料名称必填项不能为 null
            String importName = matImportQO.getName();
            if (StringUtils.isEmpty(fullCode) || StringUtils.isEmpty(importName)) {//材料编码在数据库中已存在
                logger.info("导入失败:导入数据中必填项为null===========" + matImportQO.toString());
                FmamMatImportDTO matFailFullcode = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matFailFullcode);
                matFailFullcode.setResult("导入失败:导入数据中有必填项为null");
                resultList.add(matFailFullcode);
                failNumber++;
                continue;
            }

            //校验规则2 ：准备导入的数据材料信息的 编号/(名称+规格+型号)不能重复
            String importSpec = matImportQO.getSpec();
            String importModel = matImportQO.getModel();
            String unitName = matImportQO.getUnitName();
            //2.1首先遍历数据库数据查找是否重复
            boolean dataFullcodeRepeat = false;
            boolean dataNameSpecModelRepeat = false;
            if (fmamMatDataList != null && fmamMatDataList.size() > 0) {
                for (FmamMat fmamMat : fmamMatDataList) {
                    if (fmamMat.getFullCode().equals(fullCode)) dataFullcodeRepeat = true; //编码 与数据库中重复
                    if ((fmamMat.getName() + fmamMat.getSpec() + fmamMat.getModel() + fmamMat.getUnitName()).equals(importName + importSpec + importModel + unitName))
                        dataNameSpecModelRepeat = true; //名称+规格+型号+计量单位 与数据库中重复
                }
            }
            if (dataFullcodeRepeat) {//材料编码在数据库中已存在
                logger.info("导入失败:物资编码在材料数据已存在===========" + matImportQO.toString());
                FmamMatImportDTO matFailFullcode = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matFailFullcode);
                matFailFullcode.setResult("导入失败:物资编码在材料数据已存在");
                resultList.add(matFailFullcode);
                failNumber++;
                continue;
            }
            if (dataNameSpecModelRepeat) {//材料名称+规格+型号在数据库中已存在
                logger.info("导入失败:导入物资的“名称+规格+型号+计量单位”与材料数据重复=========" + matImportQO.toString());
                FmamMatImportDTO matFailRepeat = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matFailRepeat);
                matFailRepeat.setResult("导入失败:导入物资的“名称+规格+型号+计量单位”与材料数据重复");
                resultList.add(matFailRepeat);
                failNumber++;
                continue;
            }

            //2.2遍历已经通过校验的添加数据，编号/(名称+规格+型号) 不能重复
            boolean fullcodeRepeat = false; //不存在数据重复
            boolean nameSpecModelRepeat = false;
            if (matSuccessList.size() > 0) {
                for (FmamMat fmamMatAdd : matSuccessList) {
                    if (fmamMatAdd.getFullCode().equals(fullCode)) fullcodeRepeat = true; //编码 与待添加数据中重复
                    if ((fmamMatAdd.getName() + fmamMatAdd.getSpec() + fmamMatAdd.getModel() + fmamMatAdd.getUnitName()).equals(importName + importSpec + importModel + unitName))
                        nameSpecModelRepeat = true; //名称+规格+型号+计量单位 待添加数据中重复
                }
            }
            if (fullcodeRepeat) {//物资的编号在导入数据中已存在
                logger.info("导入失败:导入物资的“编号”在导入数据中已存在===========" + matImportQO.toString());
                FmamMatImportDTO matDataRepeat = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matDataRepeat);
                matDataRepeat.setResult("导入失败:导入物资“编号”在导入数据中已存在");
                resultList.add(matDataRepeat);
                failNumber++;
                continue;
            }
            if (nameSpecModelRepeat) {//材料名称+规格+型号在待添加列表中重复
                logger.info("导入失败:导入物资的 “名称+规格+型号+计量单位”在导入数据中重复=========" + matImportQO.toString());
                FmamMatImportDTO matFailRepeat = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matFailRepeat);
                matFailRepeat.setResult("导入失败:导入物资的 “名称+规格+型号+计量单位”在导入数据中重复");
                resultList.add(matFailRepeat);
                failNumber++;
                continue;
            }

            // 校验规则 3：物资材料类型编码必须存在
            String matTypeFullCode = fullCode.substring(0, (list.get(list.size() - 2).get(list.size() - 1)));
            boolean matTypeExist = false;
            Long matTypeId = null;
            //遍历物资类型全表数据匹配存在
            for (FmamMatType fmamMatType : fmamMatTypeList) {
                if (fmamMatType.getFullCode().equals(matTypeFullCode)) {
                    matTypeExist = true;
                    matTypeId = fmamMatType.getId();
                }
            }
            if (!matTypeExist) { //材料的物资类型不存在
                logger.info("导入失败:导入物资的物资类型不存在===========" + matImportQO.toString());
                FmamMatImportDTO matFaillType = new FmamMatImportDTO();
                BeanUtils.copyProperties(matImportQO, matFaillType);
                matFaillType.setResult("导入失败:导入物资的物资类型不存在");
                resultList.add(matFaillType);
                failNumber++;
                continue;
            }

            //校验规则 4 ：如果表中填写了材料计量单位，查询计量单位是否正确
            Integer matUnitId = null;
            if (!StringUtils.isEmpty(unitName)) { //表中计量单位不为null,获取物资计量单位ID
                //遍历计量单位数据
                boolean fmamUnitExit = false;
                for (FmamUnit fmamUnit : fmamUnitList) {
                    if (fmamUnit.getName().equals(unitName)) { //如果存在，获取 id
                        fmamUnitExit = true;
                        matUnitId = fmamUnit.getId();
                    }
                }
                if (!fmamUnitExit) { //计量单位数据库中不存在
                    logger.info("导入失败:导入物资的计量单位不存在)===========" + matImportQO.toString());
                    FmamMatImportDTO matFailUnit = new FmamMatImportDTO();
                    BeanUtils.copyProperties(matImportQO, matFailUnit);
                    matFailUnit.setResult("导入失败:导入物资计量单位数据库中不存在");
                    resultList.add(matFailUnit);
                    failNumber++;
                    continue;
                }
            }

            //6、通过了所有校验，为正确数据
            FmamMat fmamMat = new FmamMat();
            BeanUtils.copyProperties(matImportQO, fmamMat);
            Double diffType = matImportQO.getDiffType();
            if (diffType != null) fmamMat.setDiffType(new Double(diffType).intValue());
            fmamMat.setRemark(matImportQO.getRemark());
            //设置材料类型ID 、计量单位ID
            fmamMat.setId(KeyGeneratorUtil.genLongId());
            fmamMat.setDeptId(deptId);
            if (!StringUtils.isEmpty(fmamMat.getName())) {
                fmamMat.setEname(PinyinUtil.toPinyinAbridge(fmamMat.getName()));
            }
            fmamMat.setMatTypeId(matTypeId);//物资类型ID
            fmamMat.setUnitId(matUnitId);//计量单位ID
            //设置其他属性
            fmamMat.setEnableFlag(EnableState.ENABLED.getValue());//默认启用状态
            fmamMat.setDelFlag(DelFlag.UNDELETE.getValue());
            Date date = new Date();
            fmamMat.setCreateTime(date);
            fmamMat.setUpdateTime(date);
            //添加结果到导入数据列表
            matSuccessList.add(fmamMat);

            //同时也添加通过校验的所有结果到导入结果输出列表
            FmamMatImportDTO matSuccess = new FmamMatImportDTO();
            BeanUtils.copyProperties(matImportQO, matSuccess);
            matSuccess.setResult("导入成功");
            resultList.add(matSuccess);
        }

        //向数据库批量插入校验判断完成后的正确数据集
        if (matSuccessList != null && matSuccessList.size() > 0) {
            fmamMatMapper.batchInsert(matSuccessList);
        }//添加物资数据完成

        FmamMatImportResultDTO importResultDTO = new FmamMatImportResultDTO();
        //导入失败的记录数
        importResultDTO.setFailNumber(failNumber);
        //导入成功的记录数
        importResultDTO.setSuccessNumber(matImportQOs.size() - failNumber);
        //导入记录
        importResultDTO.setImportResultList(resultList);
        return importResultDTO;
    }


    @Override
    public List<Long> getDescendantMatTypeIdList(Long pid) throws BizException {
        logger.info("根据材料类别id获取子孙材料类别ids服务，id:{}", pid);
        List<Long> result = new ArrayList<>();
        if (pid == null) {
            return result;
        }
        FmamMatType fmamMatType = fmamMatTypeMapper.selectByPrimaryKey(pid);
        if (fmamMatType == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该材料类型不存在");
        }
        Integer deptId = fmamMatType.getDeptId();

        //查出所有的
        List<FmamMatTypeDTO> fmamMatTypeDTOS = fmamMatTypeMapper.selectMatTypeList(deptId, null);
        for (FmamMatTypeDTO fmamMatTypeDTO : fmamMatTypeDTOS) {
            if (fmamMatTypeDTO.getPid().equals(pid)) {
                result.add(fmamMatTypeDTO.getId());
                List<Long> sonIdList = this.getSonIdList(fmamMatTypeDTO.getId(), fmamMatTypeDTOS);
                result.removeAll(sonIdList);
                result.addAll(sonIdList);
            }
        }
        result.add(pid);
        return result;
    }

    /**
     * 查找子节点
     *
     * @param pid
     * @param fmamMatTypeDTOS
     * @return
     */
    private List<Long> getSonIdList(Long pid, List<FmamMatTypeDTO> fmamMatTypeDTOS) {
        List<Long> ids = new ArrayList<>();
        for (FmamMatTypeDTO fmamMatTypeDTO : fmamMatTypeDTOS) {
            if (fmamMatTypeDTO.getPid().equals(pid)) {
                ids.add(fmamMatTypeDTO.getId());
            }
        }
        return ids;
    }

    /**
     * 获取负值
     *
     * @param minusDiff 偏差
     * @return 负偏差负值
     */
    private Double getNegative(Double minusDiff) {
        if (minusDiff == null) {
            return null;
        }
        if (minusDiff > 0) {
            minusDiff = minusDiff * -1;
        }
        return minusDiff;
    }
}


